package com.hxzy.service.impl;


import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.hxzy.common.constants.RedisConstant;
import com.hxzy.common.domain.SMSProperties;
import com.hxzy.common.enums.AckCode;
import com.hxzy.common.exception.WaimaiException;
import com.hxzy.common.vo.R;
import com.hxzy.config.WaimaiThreadLocal;
import com.hxzy.dto.back.LoginDTO;
import com.hxzy.entity.Employee;
import com.hxzy.entity.EnterpriseProcess;
import com.hxzy.entity.Merchandiser;
import com.hxzy.mapper.MerchandiserMapper;
import com.hxzy.service.EnterpriseProcessService;
import com.hxzy.service.MerchandiserService;
import com.hxzy.dto.back.MerchandiserSearchDTO;
import com.hxzy.vo.back.AdminLoginVO;
import com.hxzy.vo.front.MerchandiserProcessVO;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
* @Author wy
* @Description 商家信息业务逻辑
* @Date 2023-04-14
* @Version 1.0
*/
@Log4j2
@Service
public class MerchandiserServiceImpl extends ServiceImpl<Merchandiser,BigDecimal>  implements MerchandiserService {

    private MerchandiserMapper  merchandiserMapper;

    @Autowired
    private EnterpriseProcessService  enterpriseProcessService;

    @Autowired
    private SMSProperties smsProperties;


    @Autowired
    public void setMerchandiserMapper(MerchandiserMapper merchandiserMapper) {
        this.merchandiserMapper = merchandiserMapper;
        super.setMyBatisBaseDao(merchandiserMapper);
    }

    @Override
    public Merchandiser login(LoginDTO loginDTO) {
        Merchandiser db = this.merchandiserMapper.findByLoginName(loginDTO.getLoginName());
        return db;
    }

    @Override
    public List<Merchandiser> search(MerchandiserSearchDTO searchDTO) {
        return this.merchandiserMapper.search(searchDTO);
    }

    @Override
    public boolean existsLoginName(String loginName) {
        return this.merchandiserMapper.existsLoginName(loginName)>0;
    }

    /**
     * 做3个件情
     * 2个是数据库操作(保证数据库完整数  原子性，隔离性，一致性，持久性)
     * 1个发短信操作
     * @param entity
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean process(EnterpriseProcess entity) {
        AdminLoginVO adminLoginVO = WaimaiThreadLocal.adminThreadLocal.get();
        Merchandiser db=this.merchandiserMapper.selectByPrimaryKey(entity.getTenantId());
        if(db==null){
            throw new WaimaiException(AckCode.NOT_FOUND_DATA);
        }

        db.setStatus(entity.getStatus());
        db.setUpdateTime(new Date());
        db.setUpdateBy(adminLoginVO.getName());
        //执行
        int count = this.merchandiserMapper.updateByPrimaryKeySelective(db);

        if(count>0){
            //向审核表中添加一笔数据
            entity.setCreateBy(adminLoginVO.getName());
            entity.setCreateTime(new Date());
            count=this.enterpriseProcessService.insert(entity);

            //通知商家短信模板
            int smsId=0;

            if(db.getStatus()==0){
                smsId=1451814;
                //不影响你正常业务，不要判断
                sendSms(smsId,db.getLoginName(),null);

            }else if(db.getStatus()==2){
                smsId=1770265;
                //不影响你正常业务，不要判断
                sendSms(smsId,db.getLoginName(),entity.getDescription());
            }

            if(count>0){
                return true;
            }
        }

        return false;
    }

    /**
     * 查询商家审核历史记录
     * @param loginName
     * @return
     */
    @Override
    public MerchandiserProcessVO findProcessByLoginName(String loginName) {
        Merchandiser db = this.merchandiserMapper.findByLoginName(loginName);
        if(db==null){
            return null;
        }
        //去掉密码
        db.setLoginPwd(null);

        MerchandiserProcessVO  merchandiserProcessVO=new MerchandiserProcessVO();
        merchandiserProcessVO.setMerchandiser(db);

        //查询审核记录
        List<EnterpriseProcess> enterpriseProcessList=this.enterpriseProcessService.selectBytenantId(db.getId());
        merchandiserProcessVO.setEnterpriseProcessList(enterpriseProcessList);

        //判断最后一次提交的还未审核
        if(db.getStatus()==1){
            EnterpriseProcess  newProcess=new EnterpriseProcess();
           if(db.getUpdateTime()==null){
               newProcess.setCreateTime(db.getCreateTime());
           }else{
               newProcess.setCreateTime(db.getUpdateTime());
           }
           newProcess.setDescription("审核中，请稍心等候");
           newProcess.setStatus((short) 1);
           enterpriseProcessList.add(0,newProcess);
        }

        return merchandiserProcessVO;
    }

    @Override
    public Merchandiser existsLoginNameAndNoPassed(String loginName) {
        return this.merchandiserMapper.existsLoginNameAndNoPassed(loginName);
    }

    /**
     * 发短信
     * @param smsId
     * @param phone
     * @param description
     * @return
     */
    private boolean sendSms(int smsId,String phone,String description){

        String code = "";
        String status = "";
        try {
            Credential cred = new Credential(smsProperties.getSecretId(), smsProperties.getSecretKey());

            // 实例化一个http选项，可选，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setReqMethod("POST");
            httpProfile.setConnTimeout(60);
            /* 指定接入地域域名，默认就近地域接入域名为 sms.tencentcloudapi.com ，也支持指定地域域名访问，例如广州地域的域名为 sms.ap-guangzhou.tencentcloudapi.com */
            httpProfile.setEndpoint("sms.tencentcloudapi.com");

            /* 实例化要请求产品(以sms为例)的client对象
             * 第二个参数是地域信息，可以直接填写字符串ap-guangzhou，支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8 */
            SmsClient client = new SmsClient(cred, "ap-guangzhou");
            /* 实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数
             * 你可以直接查询SDK源码确定接口有哪些属性可以设置
             * 属性可能是基本类型，也可能引用了另一个数据结构
             * 推荐使用IDE进行开发，可以方便的跳转查阅各个接口和数据结构的文档说明 */
            SendSmsRequest req = new SendSmsRequest();

            /* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId，示例如1400006666 */
            // 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看
            String sdkAppId = smsProperties.getSdkAppId();
            req.setSmsSdkAppId(sdkAppId);

            /* 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名 */
            // 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看
            String signName = smsProperties.getSignName();
            req.setSignName(signName);

            /* 模板 ID: 必须填写已审核通过的模板 ID */
            // 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看
            String templateId = smsId+"";
            req.setTemplateId(templateId);

            /* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致，若无模板参数，则设置为空 */
            if(StrUtil.isNotBlank(description)){
                String[] templateParamSet = {description};
                req.setTemplateParamSet(templateParamSet);
            }


            /* 下发手机号码，采用 E.164 标准，+[国家或地区码][手机号]
             * 示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号 */
            String[] phoneNumberSet = {"+86" + phone};
            req.setPhoneNumberSet(phoneNumberSet);


            /* 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的
             * 返回的 res 是一个 SendSmsResponse 类的实例，与请求对象对应 */
            SendSmsResponse res = client.SendSms(req);

            // 输出json格式的字符串回包
            SendStatus[] sendStatusSetList = res.getSendStatusSet();
            for (SendStatus send : sendStatusSetList) {
                status = send.getCode();
                if(!status.equalsIgnoreCase("OK")){
                    log.error(send);
                }
            }
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
        } finally {
            //短信发送成功后，存储到redis中保存起来
          return status.equalsIgnoreCase("OK");
        }
    }
}
